import Vue from "vue";

import WidgetLib from "./dep/WidgetLib";
import SelectedWidgets from "./dep/SelectedWidgets";
import PropsController from "./dep/PropsController";
import FormPropsController from "./dep/FormPropsController";

import widgetMap from "@/lib/widgetMap";
import {
  findSelectedWidgetById,
  deepFindWidgetById
} from "@/utils/util"

import {
  Message
} from "element-ui"

export default class DragController {
  // 左侧组件库的宽度
  leftWidth = 300
  // 右侧属性面板宽度
  rightWidth = 360
  // 中间画布水平方向的margin值
  centerHorizontalMargin = 72
  constructor(formWidgets) {
    this.formWidgets = formWidgets;
    // 组件库
    this.widgetLib = new WidgetLib();
    // 画布中选中的组件
    this.selectedWidgets = new SelectedWidgets();
    // 右侧属性面板控制器
    this.propsController = new PropsController();
    // 表单的属性
    window.formPropsController = this.formPropsController = new FormPropsController();

    // 拖拽时，页面的反馈元素
    this.placeholder = null;
    // 当前拖拽时鼠标进入的组件
    this.currentDesWidget = null;
    Object.defineProperty(this, "_currentDesWidget", {
      set(val) {
        if (this.currentDesWidget && this.placeholder) {
          this.currentDesWidget.removeChild(this.placeholder)
          this.placeholder = null
        }
        this.currentDesWidget = val
      }
    })
    // 拖动画布里的 widget
    this._dragWidget = null;
  }
  initEdittingMode() {
    if (!this.formWidgets) return
    this.selectedWidgets.setWidgets(this.initSelectedWidgetsByWidgets(this.formWidgets))
    setTimeout(() => {
      this._mountForm("ultrame-canvas", true);
    }, 0)
  }
  initSelectedWidgetsByWidgets(widgets) {
    // TODO 深度初始化widgets
    return widgets.map(widget => {
      const {
        type,
        widgetProps
      } = widget
      const widgetClass = widgetMap.widgets.get(type)
      return new widgetClass(widgetProps)
    })
  }
  /**
   * 挂载 Form
   */
  _mountForm(id, editting) {
    console.log(Vue.prototype)
    const Temp = Vue.extend({
      template: this.selectedWidgets.createHtml(id, editting, this),
      data: () => {
        const reactiveData = {
          // 表单值绑定对象
          formData: {},
          // 表单验证规则
          rules: {}
        };
        const _reactiveData = (widgets) => {
          widgets.forEach((item) => {
            if (!item) return
            if (item.widgets && item.widgets.length) {
              _reactiveData(item.widgets)
            }
            if (item.widgetProps.field) {
              if (editting) {
                Vue.set(reactiveData, item.widgetProps.field, item.defaultValue)
              } else {
                Vue.set(reactiveData.formData, item.widgetProps.field, item.defaultValue);
                Vue.set(reactiveData.rules, item.widgetProps.field, [...item.requiredRule, ...(item.widgetProps.rules || [])])
              }
            }
          })
        };
        _reactiveData(this.selectedWidgets.widgets);
        return reactiveData
      },
      methods: {
        handleClick() {
          this.$refs.ultrameForm.validate((valid) => {
            if (valid) {
              console.log(this.formData)
              alert('submit!');
            } else {
              console.log('error submit!!');
              return false;
            }
          });
        },
      }
    });
    new Temp().$mount(`#${id}`);
    const canvas = document.querySelector("#ultrame-canvas")
    // 给canvas绑定点击事件，为了切换右侧控制组件属性
    canvas && canvas.addEventListener("click", (ev) => {
      let {
        id
      } = ev.target
      if (id === "ultrame-canvas") return
      // 如果点击的是栅格，则需要找到 row 的 id 对应的 widget
      if (ev.target.getAttribute("type") === "container") {
        id = ev.target.parentNode.parentNode.id
      }
      const widget = deepFindWidgetById(this.selectedWidgets.widgets, id)
      widget && this.propsController.setCurrentControl(widget)
    })
  }
  /**
   * 开始拖拽时的回调函数
   * @param {Event} ev 
   */
  _handleDragstart(ev) {
    const {
      id,
      dataset: {
        role
      }
    } = ev.target;
    ev.target.style.opacity = 0.3
    ev.dataTransfer.setData("id", id)
    ev.dataTransfer.setData("role", role)
  }
  /**
   * 拖拽进入到某个元素的回调函数
   * @param {Event} ev 
   * @returns 
   */
  _handleDragenter(ev) {
    if (!this.selectedWidgets.widgets.length) return
    const id = ev.target.id
    const type = ev.target.getAttribute("type")
    if (type === "container") {
      const dragWidgetRole = ev.dataTransfer.getData("role")
      if (dragWidgetRole === "container") return
      let _width = ev.target.clientWidth,
        _height = ev.target.clientHeight
      this._currentDesWidget = ev.target
      const {
        parentid,
        idx
      } = ev.target.dataset
      const widget = this.selectedWidgets.widgets.find(item => item.id === parentid)
      if (widget && widget.widgets[idx]) return
      if (!this.placeholder) {
        const _placeholder = document.createElement("div")
        _placeholder.style.width = _width + "px";
        _placeholder.style.height = _height + "px";
        _placeholder.style.display = "inline-block";
        _placeholder.style.background = "salmon";
        _placeholder.style.pointerEvents = "none";
        this.placeholder = _placeholder
        ev.target.appendChild(_placeholder)
      }
    } else if (["ultrame-canvas-container", "ultrame-canvas"].includes(id)) {
      const _ultrameForm = document.getElementById("ultrame-canvas")
      this._currentDesWidget = _ultrameForm
      if (!this.placeholder) {
        const _placeholder = document.createElement("div");
        _placeholder.style.width = "2px";
        _placeholder.style.heigth = "84px";
        _placeholder.style.background = "salmon";
        this.placeholder = _placeholder;
        _ultrameForm.appendChild(_placeholder);
      }
    }
  }
  /**
   * 当拖拽到其他元素上时的回调函数
   * @param {Event} ev 
   */
  _handleDragover(ev) {
    const {
      target
    } = ev
    const {
      dataset: {
        parentid
      },
      id
    } = target
    if (parentid === "ultrame-canvas") {
      if (!this._currentDesWidget) {
        const _ultrameForm = document.getElementById("ultrame-canvas")
        this._currentDesWidget = _ultrameForm
        const placeholder = document.createElement("div");
        placeholder.style.width = "2px";
        placeholder.style.heigth = "84px";
        placeholder.style.background = "salmon";
        this.placeholder = placeholder;
        const broDom = document.getElementById(id)
        broDom && _ultrameForm.insertBefore(placeholder, broDom);
      }
    }
    ev.preventDefault();
  }
  /**
   * 拖拽中松开鼠标后的回调函数
   * @param {Event} ev 
   * @returns 
   */
  _handleDrop(ev) {
    if (ev.target.id === ev.dataTransfer.getData("id")) return
    this._dragWidget = findSelectedWidgetById(this.selectedWidgets.widgets, ev.dataTransfer.getData("id"))
    const widgetType = ev.dataTransfer.getData("widgetType");
    const _widget = widgetMap.widgets.get(widgetType);
    let ins = null;
    if (_widget) {
      ins = new _widget();
    }
    const type = ev.target.getAttribute("type")
    if (type === "container") {
      const dragWidgetRole = ev.dataTransfer.getData("role")
      if (dragWidgetRole === "container") {
        this.selectedWidgets.addComp(ins || this._dragWidget)
        Message.warning("不能将容器放入其他容器中")
        this._mountForm("ultrame-canvas", true);
        return
      }
      const {
        parentid,
        idx
      } = ev.target.dataset
      const widget = this.selectedWidgets.widgets.find(item => item.id === parentid)
      if (widget && widget.widgets[idx]) {
        Message.warning("容器中已经存在组件")
        return
      }
      widget.widgets[idx] = ins || this._dragWidget
    } else if (["ultrame-canvas-container", "ultrame-canvas"].includes(ev.target.id)) {
      this.selectedWidgets.addComp(ins || this._dragWidget)
    } else {
      const idx = this.selectedWidgets.widgets.findIndex(item => item.id === ev.target.id)
      idx === -1 ?
        this.selectedWidgets.addComp(ins || this._dragWidget) :
        this.selectedWidgets.widgets.splice(idx, 0, ins || this._dragWidget)
    }

    this.propsController.setCurrentControl(ins || this._dragWidget);
    this._mountForm("ultrame-canvas", true);
  }
  /**
   * 拖拽结束的回调函数
   * @param {Event} ev 
   */
  _handleDragend(ev) {
    ev.dataTransfer.clearData();
    this._currentDesWidget = null;
    this._dragWidget = null;
  }
}